import decimal
import math
import datetime
from django.db import models
from django.db.models import Sum, F, Q
from django.db.models.signals import pre_save  # 修改之前
from django.dispatch import receiver  # 使用信号的装饰器 检测Django 模型对象字段值的变化
from django.utils import timezone
from .womai_api import WoMaiApi
from core.tools.models import Province
from django.contrib.auth import get_user_model
from apps.user_operation.models import VipBagCashAllot
from apps.order.models import TransferErrorCode
from core.tools.get_datetime import GetDateTime
from apps.supply_order.synquery import kuai_di_result
from core.tools.func_utils import FuncUtils
from core.tools.tasks import send_message
from dateutil.relativedelta import relativedelta

mai_api = WoMaiApi()
User = get_user_model()


class Banner(models.Model):
    TYPE = ((1, "首页banner"), (2, "详情页广告图"))
    banner = models.ImageField(upload_to="shop/banner/", verbose_name="图片")
    url = models.CharField(max_length=128, verbose_name="跳转链接")
    order = models.IntegerField(default=1, verbose_name="排序")
    bg_color = models.CharField(max_length=8, verbose_name="背景色", default="", blank=True, null=True)
    type = models.IntegerField(default=1, choices=TYPE, verbose_name="图片类型")

    class Meta:
        verbose_name = "banner/广告图"
        verbose_name_plural = verbose_name
        ordering = ("order",)


# 分类
class Category(models.Model):
    name = models.CharField(max_length=16, verbose_name="分类名称")

    class Meta:
        verbose_name = "产品分类"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


# 抢购时间
class StartTime(models.Model):
    start_time = models.DateTimeField(verbose_name="开始时间", default=timezone.now)

    class Meta:
        verbose_name = "抢购时间"
        ordering = ("start_time",)
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.start_time.strftime("%Y-%m-%d %H:%M:%S")


# 商品公司
class Company(models.Model):
    name = models.CharField(verbose_name="名称", max_length=32)
    sign = models.CharField(unique=True, verbose_name="标识", max_length=16)
    tel = models.CharField(verbose_name="客服电话", max_length=16)

    class Meta:
        verbose_name = "商品公司"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


# 省份仓库对应表
class AreaWareHouse(models.Model):
    province = models.OneToOneField("tools.Province", verbose_name="省份")
    p_code = models.IntegerField(verbose_name="省份编码")

    class Meta:
        verbose_name = "省份仓库对应表"
        verbose_name_plural = verbose_name


# 首页专区
class IndexPre(models.Model):
    """
    首页专区
    """
    # indexPre = (
    #     (1, "爆款专区"), (2, "买酒送油卡"), (3, "包邮专区"), (4, "会员专区"), (5, "粽子专区"),
    #     (6, "鸡鸭鱼肉专区"),
    # )
    # desc = models.IntegerField(verbose_name="首页专区", choices=indexPre, default=0, db_index=True)
    desc = models.CharField(verbose_name="首页专区", max_length=16, db_index=True)
    img = models.ImageField(verbose_name="图片", upload_to='indexpre/')
    permission = models.BooleanField(default=False, verbose_name="是否需要验证用户会员权限")
    order = models.IntegerField(verbose_name="排序", default=0)
    url = models.CharField(verbose_name="链接", blank=True, null=True, max_length=256)
    status = models.BooleanField(verbose_name="是否显示", default=True)

    class Meta:
        verbose_name = "首页专区"
        verbose_name_plural = verbose_name
        ordering = ("-order",)

    def __str__(self):
        return self.desc


# 库存管理
class InventoryManager(models.Manager):
    # 更新库存
    def update_inventory_by_province(self, goods_skus, p_code):
        """
        :param goods_num: ["goods_id","goods_id"]
        根据省份来更新省份库存
        :param p_code: 区域码
        :return:
        """
        content = mai_api.get_inventory(goods_skus, p_code)
        if content.get("error_response"):
            inventory = [{"skuid": i, "inventory": 0} for i in goods_skus.split(",")]
        else:
            inventory = content.get("Inventory")  # { "Inventory": [ { "skuid": "954018",  "inventory": "0" } ] }
        for i in inventory:
            goodsid = i.get("skuid")
            inventory = i.get("inventory")
            ware_house = AreaWareHouse.objects.get(p_code=p_code)
            goods = Goods.objects.get(goodsid=goodsid)
            inventory_queryset = self.filter(goods=goods, ware_house=ware_house)
            if inventory_queryset.exists():
                inventory_obj = inventory_queryset.first()
                inventory_obj.goods = goods
                inventory_obj.ware_house = ware_house
                inventory_obj.num = inventory
                inventory_obj.save()
            else:
                self.create(
                    goods=goods,
                    ware_house=ware_house,
                    num=inventory
                )
        return inventory

    # 更新库存
    def update_inventory_by_salesman(self, goods_num, salesman):
        """
        根据业务员来更新库存
        :param goods_num:
        :param salesman:
        :return:
        """
        county = salesman.receiverplace_set.get(default=True).county
        province = county.city.province
        return self.update_inventory_by_province(goods_num, province)

    # 去重商品
    def group_by_goods(self):
        return self.filter(num__gt=0).values("goods_id").distinct()


# 库存
class Inventory(models.Model):
    num = models.IntegerField(verbose_name="数量", default=0)
    ware_house = models.ForeignKey("AreaWareHouse", verbose_name="仓库")
    goods = models.ForeignKey("Goods", verbose_name="商品", related_name="goods_inventory")
    objects = InventoryManager()

    class Meta:
        verbose_name = "同一个商品在不同地区的库存"
        verbose_name_plural = verbose_name
        ordering = ('-id',)
        unique_together = ("ware_house", "goods")


# 配送范围
class VaildArea(models.Model):
    district = models.ForeignKey("tools.District", verbose_name="区县")
    goods_type = models.ForeignKey("GoodsType", verbose_name="商品类型")

    class Meta:
        verbose_name = "查询配送范围"
        verbose_name_plural = verbose_name
        ordering = ("-id",)


# # 其他的配送范围
# class OtherDeliveryArea(models.Model):
#


# 商品类型
class GoodsType(models.Model):
    goodsType = ((143, "生鲜"), (142, "常温"),)
    name = models.CharField(verbose_name="类型描述", blank=True, null=True, max_length=8)
    goods_type = models.IntegerField(verbose_name="发布标识", choices=goodsType, default=142)

    class Meta:
        verbose_name = "商品类型"
        verbose_name_plural = verbose_name

    def __str__(self):
        return "%s" % self.name


# 会员价格系数
class PriceVipCoe(models.Model):
    """
    系数
    """
    coe = models.DecimalField(verbose_name="调节系数", help_text="小数", max_digits=3, decimal_places=2)
    update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")

    class Meta:
        verbose_name = "调节系数"
        verbose_name_plural = verbose_name


class GoodsManager(models.Manager):
    def update_vip_sales_price(self, instance, coe):
        """
        :param coe: 系数
        :param instance: 实例
        :return:
        """
        if instance.cost and instance.sales_price:
            instance.sales_price_isvip = self.vip_sales(instance.cost, instance.sales_price, coe=coe)
            instance.save()

    # 如果PriceVipCoe 更新就更新商品的会员价格
    @staticmethod
    @receiver(pre_save, sender="supply_order.PriceVipCoe")  # 修改会员系数时
    def update_vip_price(sender, **kwargs):
        # sender 接收的类对象  instance 保存后的实例
        instance = kwargs.get("instance")
        if instance._state.adding:
            # 如果是新添加
            for i in Goods.objects.filter(company__sign="womaiwang"):
                Goods.objects.update_vip_sales_price(i, instance.coe)
                # i.update_vip_sales_price(instance.coe)
        else:
            # 如果是修改
            before_instance = sender.objects.first()
            if before_instance.coe != instance.coe:
                # 只有系数发生变化才会更新
                for i in Goods.objects.filter(company__sign="womaiwang"):
                    Goods.objects.update_vip_sales_price(i, instance.coe)

    # 计算会员价格  旧的
    # @staticmethod
    # def vip_sales(cost, price, coe=None):
    #     """
    #     :param cost: 成本价
    #     :param price: 卖价
    #     :param coe: 系数
    #     :return:
    #     """
    #     # 成本价 + (普通用户价 - 成本价) * x * 1.16  一般纳税人
    #     # (成本价 + (普通用户价 - 成本价) * x ) * 1.03  小微
    #     if not coe:
    #         coe = PriceVipCoe.objects.first().coe
    #     little_we = (cost + (price - cost) * coe) * decimal.Decimal(1.03)
    #     normal_people = cost + (price - cost) * coe * decimal.Decimal(1.16)
    #     little_we = round(little_we)
    #     normal_people = round(normal_people)
    #     return little_we if little_we > normal_people else normal_people

    @staticmethod
    def vip_sales(cost, price, coe=0.65):
        # 会员价=成本价＋（普通用户价-成本价）*0.65
        return cost + (price - cost) * decimal.Decimal(coe)

    # 获取商品重量
    def get_goods_weight(self, goods_num_list):
        """
        :param goods_num_list: [{"goodsid":1, "num":3},{"goodsid":2, "num":2}]
        :return:
        """
        type_143 = 0
        type_142 = 0
        for i in goods_num_list:
            goods_obj = i.get("goods")
            if goods_obj.post_fee > 0:
                if goods_obj.goodstype.goods_type == 142:
                    if goods_obj.weight:
                        goods_weight = i.get("num") * int(goods_obj.weight)
                    else:
                        goods_weight = 0
                    type_142 += goods_weight
                else:
                    if goods_obj.weight:
                        goods_weight = i.get("num") * int(goods_obj.weight)
                    else:
                        goods_weight = 0
                    type_143 += goods_weight
        return type_142, type_143

    # 获取不同价格类型的价格
    def get_diff_type_fee(self, goods_num_list):
        """
        获得省钱额度
        :param goods_num_list: [{"goodsid":1, "num":3},{"goodsid":2, "num":2}]
        :return:
        """
        sales_price = 0
        vip_price = 0
        cost_price = 0
        for i in goods_num_list:
            goods_obj = i.get("goods")
            if goods_obj.is_vip_bag or goods_obj.promotion:
                pass
            else:
                sales_price += goods_obj.total_fee(i.get("num"))
                vip_price += goods_obj.total_fee_is_vip(i.get("num"))
                cost_price += goods_obj.cost_fee(i.get("num"))
        return sales_price, vip_price, cost_price

    # 会员省额度
    def get_save_money(self, goods_num_list):
        sales_price, vip_price, cost_price = self.get_diff_type_fee(goods_num_list)
        return sales_price - vip_price

    # 直推赚多少钱
    def leader_make_money(self, goods_num_list):
        price_spread = self.get_save_money(goods_num_list)
        return math.floor(price_spread * 0.3)

    # 平台毛利
    def get_gross_margin(self, goods_num_list):
        sales_price, vip_price, cost_price = self.get_diff_type_fee(goods_num_list)
        # (sales_price - vip_price) * 0.3 * 1.43  推广赚
        # vip_price 卖价（会员买就是会员价，普通用户买就是销售价-会员价给推荐人，所以价格一样）
        # 卖价-佣金价格-成本价=平台毛利
        gross_margin = vip_price - (sales_price - vip_price) * 0.3 * 1.43 - cost_price
        return gross_margin


class Goods(models.Model):
    stock = models.IntegerField(default=999999, verbose_name="库存")
    high_rebates = models.BooleanField(default=False, verbose_name="是否是高佣金专区")
    index_pre = models.ForeignKey("IndexPre", verbose_name="首页专区", blank=True, null=True)
    goodstype = models.ForeignKey("GoodsType", verbose_name="发布标识", blank=True, null=True)
    goodsid = models.CharField(verbose_name="产品id", db_index=True, max_length=16)
    weight = models.CharField(verbose_name="重量", blank=True, null=True, max_length=8)
    brandName = models.CharField(verbose_name="品牌名称", blank=True, null=True, max_length=64)
    goodsname = models.CharField(verbose_name="商品名称", blank=True, null=True, max_length=64)
    place_production = models.CharField(verbose_name="商品产地", blank=True, null=True, max_length=128)
    goodsbarcode = models.CharField(verbose_name="条形码", blank=True, null=True, max_length=64)
    unit = models.CharField(verbose_name="单位", blank=True, null=True, max_length=16)
    prodescription = models.TextField(verbose_name="描述", blank=True, null=True)
    specification = models.CharField(verbose_name="规格", blank=True, null=True, max_length=32)
    pubflag = models.CharField(verbose_name="发布标识", blank=True, null=True, max_length=32)
    category = models.CharField(verbose_name="类别编号", blank=True, null=True, max_length=32)
    categoryid = models.CharField(verbose_name="类别编号id", blank=True, null=True, max_length=32)
    sales_price = models.IntegerField(verbose_name="销售价格", help_text="以分为单位", default=0)
    # 只有促销价格非零的时候才会按促销价格来卖
    promotion = models.IntegerField(verbose_name="促销价格", default=0)
    other_shop_sales_price = models.IntegerField(verbose_name="其他平台价格", help_text="其他平台价格", default=0)
    sales_price_isvip = models.IntegerField(verbose_name="会员销售价格", help_text="以分为单位", default=0)
    cost = models.IntegerField(verbose_name="成本价", help_text="以分为单位", default=0)
    is_vip_bag = models.BooleanField(default=False, verbose_name="是否是会员礼包", db_index=True)
    post_fee = models.IntegerField(verbose_name="运费", help_text="以分为单位，如果是0说明包邮", default=0)
    create_time = models.DateTimeField(verbose_name="创建时间", default=timezone.now)
    company = models.ForeignKey("Company", verbose_name="商品公司")
    active_start_time = models.ForeignKey("StartTime", blank=True, null=True, verbose_name="抢购时间")
    system_category = models.ForeignKey("Category", blank=True, null=True, verbose_name="优品系统分类")
    can_sale = models.BooleanField(verbose_name="上架", default=True)
    ordering = models.IntegerField(verbose_name="排序", default=1)
    attribute = models.ManyToManyField("GoodsAttribute", verbose_name="商品", related_name="attribute_goods_set",
                                       blank=True, null=True)

    objects = GoodsManager()

    class Meta:
        verbose_name = "商品信息"
        verbose_name_plural = verbose_name
        ordering = ("ordering", "-id")

    # 获取会员价
    def get_vip_price(self):
        if self.is_vip_bag:
            return self.sales_price * 0.75
        else:
            return self.sales_price_isvip

    # 获取购买时单价(返回价格，和订单状态 ((1, "正常商品"), (2, "会员礼包"), (3, "会员礼包复购")))
    def get_buy_price(self, user):
        if self.is_vip_bag:
            if user.is_authenticated:
                if user.level.level > 1:
                    return self.sales_price * 0.75, 3
                else:
                    return self.sales_price, 2
            else:
                return self.sales_price, 2
        elif self.promotion:
            if user.is_authenticated:
                if user.level.level > 1:
                    return self.promotion, 1
                else:
                    return self.sales_price, 1
            else:
                return self.sales_price, 1
        else:
            if user.is_authenticated:
                if user.level.level > 1:
                    return self.sales_price_isvip, 1
                else:
                    return self.sales_price, 1
            else:
                return self.sales_price, 1

    # 购买时的总价,单价,是否是促产品,
    def get_total_fee_price(self, user, num):
        is_promotion = False
        if self.promotion:
            is_promotion = True
        price, order_type = self.get_buy_price(user)
        total_fee = price * num
        return total_fee, price, is_promotion, order_type

    def total_fee(self, num):
        """
        普通用户价格
        :return:
        """
        return num * self.sales_price

    def total_fee_is_vip(self, num):
        """
        会员价格
        :return:
        """
        return num * self.sales_price_isvip

    def total_fee_promotion(self, num):
        """
        获取促销价格
        :param num:
        :return:
        """
        return num * self.promotion

    def cost_fee(self, num):
        """
        成本价
        :param num:
        :return:
        """
        return num * self.cost

    def update_detail(self, **kwargs):
        """
        主要跟新我买网产品详情，价格
        :return:
        """
        for k, v in kwargs.items():
            self.__dict__[k] = v
            self.save()

    # def save(self, force_insert=False, force_update=False, using=None,
    #          update_fields=None):
    #     if self.company.sign == "womaiwang":
    #         vip_coe = PriceVipCoe.objects.first()
    #         if self.cost and self.sales_price and vip_coe:
    #             self.sales_price_isvip = Goods.objects.vip_sales(self.cost, self.sales_price)
    #         else:
    #             pass
    #     super(Goods, self).save(force_insert=force_insert, force_update=force_update, using=using,
    #                             update_fields=update_fields)

    def __str__(self):
        return "%s  %s" % (self.id, self.goodsname)


class GoodsImage(models.Model):
    imgType = ((1, "首页图"), (2, "详情页图"), (3, "提交订单图"), (4, "详情页上面的轮播图"))
    goods = models.ForeignKey("Goods", verbose_name="商品", related_name="goods_images")
    path = models.CharField(max_length=512, verbose_name="图片链接")
    isprimary = models.IntegerField(verbose_name="排序", default=0)
    type = models.IntegerField(choices=imgType, default=1, verbose_name="图片类型")

    class Meta:
        verbose_name = "商品图片"
        verbose_name_plural = verbose_name
        ordering = ("isprimary",)

    def update_path(self, path):
        self.path = path
        self.save()


class ReceiptDetails(models.Model):
    content = models.TextField(verbose_name="发票内容")
    ereceiptaddress = models.CharField(verbose_name="发票接收邮箱", blank=True, null=True, max_length=32)
    taxpayerid = models.CharField(verbose_name="纳税人识别号", max_length=32, blank=True, null=True)
    receiptdetails = models.TextField(verbose_name="发票内容", blank=True, null=True)

    class Meta:
        verbose_name = "发票内容"
        verbose_name_plural = verbose_name


class ReceiverPlaceManager(models.Manager):
    def update_default(self, user, default=False):
        """
        :param user: 用户
        :param default:
        :return:
        """
        self.filter(user=user).update(default=default)

    # 通过更新时间来更新默认值
    def update_default_by_update_time(self, user):
        place_obj = self.filter(user=user).order_by("-update_time").first()
        place_obj.default = True
        place_obj.save()


# 收货地址
class ReceiverPlace(models.Model):
    default = models.BooleanField(verbose_name="是否是默认地址", default=False)
    user = models.ForeignKey(User, verbose_name="用户", related_name="user_receiver_info")
    province = models.CharField(verbose_name="省", max_length=32)
    city = models.CharField(verbose_name="市", max_length=32)
    county = models.CharField(verbose_name="县", max_length=32)
    # county = models.ForeignKey("tools.District", verbose_name="县城")
    postcode = models.CharField(max_length=16, verbose_name="邮编", blank=True, null=True)
    receiver_mobile = models.CharField(max_length=16, verbose_name="收货人手机")
    receiver_name = models.CharField(max_length=16, verbose_name="收货人姓名")
    receiver_phone = models.CharField(max_length=16, verbose_name="收货人电话", blank=True, null=True)
    update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    remark = models.TextField(verbose_name="详细地址")
    status = models.BooleanField(default=True, verbose_name="是否删除")
    objects = ReceiverPlaceManager()

    class Meta:
        verbose_name = "收货地址"
        verbose_name_plural = verbose_name
        ordering = ('-update_time',)

    def __str__(self):
        return "%s" % self.id


class CartItemManager(models.Manager):
    def get_cart(self, salesman):
        return self.filter(salesman=salesman)

    def cart_total_fee(self, salesman, cart_id_list=list()):
        """
        获取总价格
        :param salesman:
        :param cart_id_list:
        :return:
        """
        cart_item = self.get_cart(salesman)
        if cart_id_list:
            cart_item = cart_item.filter(id__in=cart_id_list)
        if salesman.user_type == 1:
            price = 0
            for i in cart_item:
                price += i.goods.total_fee(i.num)
        else:
            price = 0
            for i in cart_item:
                price += i.goods.total_fee_is_vip(i.num)
        return price

    def cart_total_fee_round_2(self, salesman, cart_id_list=list()):
        total_price = self.cart_total_fee(salesman, cart_id_list=list())
        total_price /= 100.0
        total_price = round(total_price, 2)
        return total_price


# 购物车
class CartItem(models.Model):
    """
    购物车
    """
    STATUS = ((1, "正常"), (2, "已经购买"), (3, "删除"))
    user = models.ForeignKey(User, verbose_name="用户")
    goods = models.ForeignKey("Goods", verbose_name="商品")
    num = models.IntegerField(verbose_name="数量")
    create_time = models.DateTimeField(default=timezone.now, verbose_name="创建时间")
    update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    status = models.IntegerField(verbose_name="状态", choices=STATUS, default=1)
    # 一个商品对应多个价格（价格里）
    goods_price = models.ForeignKey("GoodsPrice", verbose_name="商品价格", blank=True, null=True,
                                    related_name="goods_price_set")
    objects = CartItemManager()

    class Meta:
        verbose_name = "购物车"
        verbose_name_plural = verbose_name
        ordering = ("-update_time",)

    def total_fee(self):
        """
        普通会员价格
        :return:
        """
        return self.num * self.goods.sales_price

    def total_fee_is_vip(self):
        """
        vip价格
        :return:
        """
        return self.num * self.goods.sales_price_isvip

    def delete_item(self):
        """
        删除购物车里的订单
        :return:
        """
        self.status = 2
        self.save()


class LogisticsManager(models.Manager):
    def get_order(self, user=None):
        queryset = WomaiOrder.objects.filter(order_status__in=[2, 3])
        if user:
            queryset = queryset.filter(supply_order__user=user)
        return queryset

    def logistics_detail(self, main_order):
        try:
            logistics_obj = self.get(
                order=main_order,
                update_time__lt=GetDateTime.get_tow_hours_ago(),
                ischeck=False
            )
            if not logistics_obj.ischeck:
                content = kuai_di_result(logistics_obj.post_company.code, logistics_obj.code)
                if content.get("status") and content.get("status") == "200":
                    data = content.get("data")
                    for i in data:
                        PostRecord.objects.get_or_create(
                            logistics=logistics_obj,
                            remark=i.get("context"),
                            create_time=i.get("ftime"),
                            other_state_code=i.get("state"),
                            statename=i.get("context"),
                        )
                    logistics_obj.ischeck = content.get("ischeck")
                    logistics_obj.update_time = datetime.datetime.now()
                    logistics_obj.save()
        except Exception as e:
            print(e)

            # def logistics(self, user=None):
            #     queryset = self.get_order(user=user)
            #     for item in queryset:
            #         if item.company.sign == "womaiwang":
            #             pass
            #         else:
            #             try:
            #                 logistics_obj = self.get(
            #                     order=item,
            #                     update_time__gt=GetDateTime.get_tow_hours_ago()
            #                 )
            #                 if not logistics_obj.ischeck:
            #                     content = kuai_di_result(logistics_obj.post_company.code, logistics_obj.code)
            #                     if content.get("status") and content.get("status") == "200":
            #                         data = content.get("data")
            #                         for i in data:
            #                             PostRecord.objects.get_or_create(
            #                                 logistics=logistics_obj,
            #                                 remark=i.get("context"),
            #                                 create_time=i.get("ftime"),
            #                                 other_state_code=i.get("state"),
            #                                 statename=i.get("context"),
            #                             )
            #                         logistics_obj.ischeck = content.get("ischeck")
            #                         logistics_obj.update_time = datetime.datetime.now()
            #                         logistics_obj.save()
            #             except Exception as e:
            #                 print(e)

    def logistics_detail_wm(self, main_order):
        from apps.supply_order.womai_api import WoMaiApi
        try:
            logistics_obj, created = self.get_or_create(
                order=main_order,
            )
            if not logistics_obj.ischeck:
                content = WoMaiApi().get_logistics(main_order.tid).get("logistics")
                code = None
                ischeck = False
                for i in content:
                    # a = {'tid': '19121016442326836688', 'ordercode': None, 'stationname': '北京朝阳区芍药居站中粮我买网配送', 'statecode': '506', 'statename': '配送成功', 'remark': 'BBCZC191210003064||订单已签收', 'createtime': '2019/12/11 10:24:23'}
                    if i.get("statecode") == "506":
                        other_state_code = 3
                        ischeck = True
                    elif i.get("statecode") == "505":
                        other_state_code = 0
                    elif i.get("statecode") == "501":
                        other_state_code = 1
                    else:
                        other_state_code = i.get("statecode")
                    PostRecord.objects.get_or_create(
                        logistics=logistics_obj,
                        remark=i.get("remark"),
                        create_time=i.get("createtime").replace("/", "-"),
                        other_state_code=other_state_code,
                        statename=i.get("statename"),
                        stationname=i.get("stationname"),
                    )
                    code = i.get("remark").split("||")[0]
                logistics_obj.ischeck = ischeck
                logistics_obj.update_time = datetime.datetime.now()
                logistics_obj.code = code
                logistics_obj.save()
        except Exception as e:
            print(e)


# 物流信息
class Logistics(models.Model):
    """
    物流信息
    """
    code = models.CharField(verbose_name="物流单号", blank=True, null=True, max_length=64)
    post_company = models.ForeignKey("PostCompany", blank=True, null=True)
    order = models.OneToOneField("WomaiOrder", verbose_name="主订单")
    update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间", help_text="查询频率间隔最好为1-2小时。")
    create_time = models.DateTimeField(default=timezone.now, verbose_name="创建时间", help_text="创建时间")
    ischeck = models.BooleanField(verbose_name="是否签收", default=False)
    objects = LogisticsManager()

    class Meta:
        # ordering = ("-update_time",)
        verbose_name = "物流信息"
        verbose_name_plural = verbose_name


# 物流记录
class PostRecord(models.Model):
    logistics = models.ForeignKey("Logistics", verbose_name="物流记录", related_name="logistics_record")
    otherStateCode = ((0, "在途中"), (1, "已揽收"), (2, "疑难"), (3, "已签收"), (4, "退签"), (5, "同城派送中"),
                      (6, "退回"), (7, "转单"))
    other_state_code = models.IntegerField(blank=True, null=True, verbose_name="其他商家的物流状态码")
    statecode = models.IntegerField(verbose_name="操作代码", blank=True, null=True, choices=otherStateCode)
    statename = models.CharField(verbose_name="操作名称", max_length=256, blank=True, null=True)
    remark = models.CharField(max_length=256, verbose_name="描述", blank=True, null=True,
                              help_text="因为是我买网的商品，这里api中用来代表第三方快递公司运单号")
    stationname = models.CharField(max_length=256, verbose_name="配送商名称", blank=True, null=True)
    create_time = models.DateTimeField(default=timezone.now, verbose_name="操作时间", help_text="我买网返回时间")

    class Meta:
        ordering = ("-create_time",)
        verbose_name = "物流记录"
        verbose_name_plural = verbose_name


class SupplyOrderManager(models.Manager):
    def create_order(self, user, total_fee=0, buyer_message=None, out_trade_no=None):
        """
        :param user: 用户
        :param total_fee: 总金额
        :param buyer_message: 买家留言
        :param out_trade_no: 交易订单号
        :return:
        """
        # 收货地址
        receiver_place = ReceiverPlace.objects.get(user=user, default=True)
        base_order = self.create(
            user=user,
            total_fee=total_fee,
            receipt_place=receiver_place,
            buyer_message=buyer_message,
            out_trade_no=out_trade_no,
        )
        base_order.save()
        return base_order


class SupplyOrder(models.Model):
    """
    主订单
    """
    pay_type = ((0, "未付"),
                (1, "微信支付"),
                (2, "api支付,对方收款"),
                (3, "通联支付"),
                (4, "银联支付"),
                (5, "银联小程序支付"),
                )
    is_active = models.BooleanField(default=False, verbose_name="默认不生效", db_index=True)
    wx_pay_type = models.IntegerField(default=0, db_index=True, choices=pay_type)
    out_trade_no = models.CharField(max_length=64, verbose_name="商户系统内部订单", blank=True, null=True,
                                    db_index=True)
    user = models.ForeignKey(User, verbose_name="购买用户")
    receipt_place = models.ForeignKey(ReceiverPlace, verbose_name="收货地址", blank=True, null=True)
    total_fee = models.IntegerField(verbose_name="商品金额", help_text="商品金额", blank=True, null=True)
    pose_fee = models.IntegerField(verbose_name="运费合计", default=0)
    payment = models.IntegerField(verbose_name="实付金额，含运费", help_text="根据此字段开发票", blank=True, null=True)
    modified = models.DateTimeField(default=timezone.now, verbose_name="交易修改时间", help_text="修改交易类型时间")
    created_time = models.DateTimeField(default=timezone.now, verbose_name="创建时间")
    # 完成付款后更新
    pay_time = models.DateTimeField(verbose_name="付款时间", blank=True, null=True)
    # 第一版不考虑
    receipt = models.ForeignKey(ReceiptDetails, verbose_name="发票信息", blank=True, null=True)
    buyer_message = models.TextField(verbose_name="买家留言", blank=True, null=True)
    receipt_type = models.BooleanField(verbose_name="是否需要发票", default=False)

    objects = SupplyOrderManager()

    class Meta:
        verbose_name = "供应订单"
        verbose_name_plural = verbose_name

    def update_trade_type_fixed(self, pay_type=1):
        now_time = datetime.datetime.now()
        self.wx_pay_type = pay_type
        self.modified = now_time
        self.pay_time = now_time
        self.save()

    def update_out_trade_no(self, out_trade_no=None):
        if out_trade_no:
            self.out_trade_no = out_trade_no
        else:
            self.out_trade_no = FuncUtils().unique_value
        self.save()
        return self.out_trade_no


class WomaiOrderManager(models.Manager):
    @staticmethod
    def add_trade(wm_order):
        """
        整理提交订单的数据
        :param wm_order:  主订单
        :return:
        """
        tid = wm_order.tid  # 主订单号
        receiver = wm_order.supply_order.receipt_place  # 收货地址
        create_time = wm_order.supply_order.created_time.strftime("%Y-%m-%d %H:%M:%S")
        child_order = wm_order.child_order.all()
        data = {
            "trade": {
                "trade_add_request": {
                    "trade": {
                        "buyer_message": wm_order.buyer_message,
                        "total_fee": wm_order.total_fee / 100.0,  # 我买网的总价格,
                        "payment": wm_order.payment / 100.0,  # 我买网的付款金额
                        "post_fee": wm_order.post_fee / 100.0,  # 我买网的邮费,
                        "trade_type": "presale",  # 预订单
                        "adjust_fee": 0,
                        "buyer_nick": receiver.receiver_name,  # 买家昵称
                        "created": create_time,
                        "discount_fee": 0,
                        "receiver_name": receiver.receiver_name,  # 收货人姓名
                        "receiver_state": receiver.province,  # 省
                        "receiver_city": receiver.city,  # 市
                        "receiver_district": receiver.county,  # 区
                        "receiver_address": receiver.remark,  # 详细地址
                        "receiver_mobile": receiver.receiver_mobile,  # 手机号,
                        "tid": tid,
                        "isverifyinventory": 1,  # 验证库存
                        "orders": {
                            "order": [
                                {
                                    "tid": tid,  # 主订单号
                                    "num": i.num,  # 数量
                                    "oid": i.oid,  # 子订单号
                                    "total_fee": i.total_fee / 100.0,  # 总价格
                                    "price": i.price / 100.0,  # 单价
                                    "outer_iid": str(i.goods.goodsid),  # 我买商品编码
                                    "title": i.goods.goodsname  # 商品名称
                                } for i in child_order
                            ]
                        }
                    }
                }
            }
        }
        return data

    def update_order(self, data, old_porder):
        """
        查询订单之后，判断是否有拆单行为，然后将其拆单，分别创建数据
        :param data:
        :param old_porder: 老的订单
        :return:
        """
        my_order_type = data.get("type")  # 根据它来判断是子订单还是要拆主订单
        # 不需要拆单
        if my_order_type.isdigit() and int(my_order_type) == 2:
            old_porder.update_search_result(data, commit=False)
            old_porder.check_status = 1
            old_porder.save()
        # 需要拆单
        elif my_order_type.isdigit() and int(my_order_type) == 1:
            cOrder = data.get("cOrder")
            # 创建拆单订单
            c_order_len = len(cOrder)
            post_fee = int(old_porder.post_fee / c_order_len)
            for c in cOrder:
                # 创建新的父订单
                p_order = self.create(
                    post_fee=post_fee,
                    check_status=2,
                    supply_order=old_porder.supply_order,
                    tid=c.get("supplierOrderId"),
                    ordercode=c.get("orderState"),
                    state=c.get("state"),
                    submitstate=c.get("submitState"),
                    company=old_porder.company
                )
                sku = c.get('sku')
                # 更新子订单
                for s in sku:
                    c_order = WomaiChildOrder.objects.get_order_by_sku(old_porder, s.get("skuId"))
                    c_order.update_wm_order(p_order)
            old_porder.update_status(3)  # 更新成 被拆过的订单(不需要展示)
        # 有错误，不更新
        else:
            pass

    def get_order(self, user=None):
        start_time = GetDateTime.get_tow_hours_ago()
        queryset = self.filter(supply_order__created_time__lte=start_time, order_status=1)
        if user:
            return queryset.filter(supply_order__user=user)
        return queryset

    def cancel_order(self, user=None):
        queryset = self.get_order(user=user)
        for i in queryset:
            if i.company.sign == "womaiwang":
                mai_api.goods_trade_cancel(i.tid)
        queryset.update(
            order_status=5
        )


# 我买主订单
class WomaiOrder(models.Model):
    """
    1、这个表需要对应物流信息
    """
    submitState = ((0, "取消订单或者拒收"), (1, "确认下单订单"))
    orderState = ((0, "未确认下单订单"), (1, "有效"), (2, "挂起"))
    checkStatus = ((0, "未检查"), (1, "不需要拆单"), (2, "已经拆好的订单"), (3, "被拆过的订单(不需要展示)"))
    orderStatus = ((1, "待付款"), (2, "待发货"), (3, "待收货"), (4, "已完成"), (5, "已取消"), (6, "完成售后"))
    TradeType = (("presale", "预订单(待付款订单)"),
                 ("fixed", "已付款订单"),
                 ("cancel", "取消订单")
                 )
    buyer_message = models.TextField(verbose_name="买家留言", blank=True, null=True)
    trade_type = models.CharField(choices=TradeType, verbose_name="交易类型", default="presale", max_length=16)
    company = models.ForeignKey("Company", verbose_name="公司", blank=True, null=True)  # 查询订单需要根据不同公司调用不同接口
    supply_order = models.ForeignKey("SupplyOrder", verbose_name="基础订单", related_name="main_base_order")
    tid = models.CharField(verbose_name="我们提供的单号", unique=True, max_length=35)
    ordercode = models.CharField(verbose_name="我买网订单号", max_length=25, blank=True, null=True, db_index=True)
    check_status = models.IntegerField(verbose_name="查询状态", choices=checkStatus, default=0)
    order_state = models.IntegerField(verbose_name="我买网订单状态", choices=orderState, default=1)
    order_status = models.IntegerField(verbose_name="订单状态", choices=orderStatus, default=1)
    submitstate = models.IntegerField(verbose_name="下单状态", choices=submitState, default=0)
    update_time = models.DateTimeField(verbose_name="更新时间", default=timezone.now)
    post_fee = models.IntegerField(verbose_name="运费", default=0)
    receivable_post_fee = models.IntegerField(verbose_name="应收运费", default=0)
    total_fee = models.IntegerField(verbose_name="商品总价格", default=0)
    payment = models.IntegerField(verbose_name="实付金额，含运费", default=0)
    is_delete = models.BooleanField(verbose_name="是否删除", default=False)
    # buyer_msg = models.TextField(verbose_name="买家留言", blank=True, null=True)
    objects = WomaiOrderManager()

    class Meta:
        verbose_name = "我买网订单"
        verbose_name_plural = verbose_name
        ordering = ("-update_time",)

    def update_status(self, check_status, commit=True):
        """
        更新订单检查状态
        :param check_status:
        :param commit:
        :return:
        """
        self.check_status = check_status
        if commit:
            self.save()

    def update_search_result(self, data, commit=True):
        """
        更新查询结果
        :return:
        """
        self.state = data.get("state")
        self.ordercode = data.get("orderstate")
        self.submitstate = data.get("submitstate")
        if commit:
            self.save()

    # 通过子订单获取商品总价
    def get_total_price_by_child(self):
        return self.child_order.aggregate(total_fee=Sum("total_fee")).get("total_fee")

    # 取消订单
    def cancel_order_obj(self):
        if self.company.sign == "womaiwang":
            context = mai_api.goods_trade_cancel(self.tid)
            print(context)

    def __str__(self):
        return str(self.id)


class WomaiChildOrderManager(models.Manager):
    """
    我买网子订单
    """

    def get_order_by_sku(self, wm_order, sku):
        """
        根据我买网的sku来查找订单
        :param wm_order:
        :param sku:
        :return:
        """
        return self.get(wm_order=wm_order, goods__goodsid=sku)

    def get_after_sale(self):
        """
        待处理的售后
        :return:
        """
        # return self.filter(~Q(after_sale__in=[0, 3, 4]))
        return self.filter(~Q(after_sale=0))

    def update_pay_result(self, s_order, pay_type='wx'):
        # from .utils import SendShortMessageThread, CreateIncomeThread, UpdatePrefThread
        # from .utils import update_pref, create_income
        from .tasks import task_update_pref, task_create_income
        main_order = s_order.main_base_order.all()
        if self.filter(order_type=2, wm_order__in=main_order):
            # if order_type == 2:  # 如果购买了会员礼包
            user = s_order.user
            user.recommend()  # 升级会员
            # content = "【优品会员】恭喜您邀请的%s（%s），ID:%s 已成为会员。快邀请同学们一起买，一起赚吧……" % (user.name, user.mobile, user.id)
            # send_message.delay(user.leader.mobile, content)
            user.oil_flag = True
            now_day = datetime.date.today()
            user.oil_flag_expiry_date = now_day + relativedelta(months=12)
            user.save()
        main_order.exclude(company__sign="womaiwang").update(
            trade_type="fixed",
            order_status=2
        )
        if main_order.filter(company__sign="womaiwang").exists():
            womai_order_obj = main_order.get(company__sign="womaiwang")
            if womai_order_obj.trade_type == "presale":
                # 如果是预订单的时候再去确认下单
                context = mai_api.goods_trade_confirm(womai_order_obj.tid)
                if context.get("result") == "true":
                    # 更新我买网的订单
                    main_order.filter(company__sign="womaiwang").update(
                        trade_type="fixed",
                        order_status=2
                    )
                    # 这里增加一个else，发送微信消息，确认订单
                    # 更新收益数据
        # 异步
        task_create_income.delay(s_order.id, income_order_id=s_order.id)
        task_update_pref.delay(s_order.id, update_pref_order_id=s_order.id)
        # # 同步
        # create_income(s_order)
        # update_pref(s_order)
        # # 线程
        # try:
        #     CreateIncomeThread(s_order).start()
        # except Exception as e:
        #     print(pay_type, e)
        #     CreateIncomeThread(s_order).start()
        # try:
        #     UpdatePrefThread(s_order).start()
        # except Exception as e:
        #     print(pay_type, e)
        #     UpdatePrefThread(s_order).start()


# 子订单
class WomaiChildOrder(models.Model):
    # 自定 计算收益（主订单已完成，子订单无需售后，方可结算佣金， 或者换货成功）
    orderType = ((1, "正常商品"), (2, "会员礼包"), (3, "会员礼包复购"))
    State = ((0, "新建"), (1, "妥投"), (2, "拒收"), (3, "退货"), (4, "换货"), (5, "未收到货"))
    afterSale = ((0, "不需要售后"), (1, "发起售后"), (2, "商家介入"), (3, "换货成功"), (4, "退款成功"), (5, "拒绝售后"))
    afterType = ((1, "退款"), (2, "换货"),)
    postFeeStatus = ((1, "不需要退运费"), (2, "需要退运费"))
    post_fee_status = models.IntegerField(choices=postFeeStatus, blank=True, null=True, verbose_name="运费退款状态")
    after_type = models.IntegerField(verbose_name="退款类型", blank=True, null=True, choices=afterType)
    refund = models.OneToOneField("RefundRecord", verbose_name="退款详情", blank=True, null=True)
    after_sale = models.IntegerField(choices=afterSale, default=0, verbose_name="退款状态")
    wm_order = models.ForeignKey("WomaiOrder", verbose_name="基础订单", related_name="child_order")
    user_level = models.ForeignKey("user_operation.LevelDesc", blank=True, null=True, verbose_name="当前购买用户身份",
                                   related_name="user_level_child_order")
    is_promotion = models.BooleanField(default=False, verbose_name="是否是促销价格")
    goods = models.ForeignKey("Goods", verbose_name="产品信息")
    # 增加商品价格信息
    goods_price = models.ForeignKey("GoodsPrice", verbose_name="商品价格属性", blank=True, null=True)
    oid = models.CharField(verbose_name="订单号", help_text="不可重复,长度25字符以内", unique=True, max_length=25)
    num = models.IntegerField(verbose_name="购买数量", default=1)
    price = models.IntegerField(verbose_name="商品单价", blank=True, null=True)
    cost = models.IntegerField(verbose_name="当前成本价格", help_text="以分为单位", default=0)
    total_fee = models.IntegerField(verbose_name="总金额", help_text="商品单价乘以数量的总金额", blank=True, null=True)
    state = models.IntegerField(verbose_name="状态", choices=State, default=0)
    update_time = models.DateTimeField(verbose_name="订单更新时间", auto_now=True)
    apply_refund_time = models.DateTimeField(verbose_name="申请退款时间", default=timezone.now)
    shop_remark = models.TextField(verbose_name="商家标记的备注", blank=True, null=True)
    order_type = models.IntegerField(verbose_name="订单类型", choices=orderType, default=1)
    objects = WomaiChildOrderManager()

    class Meta:
        verbose_name = "我买网子订单"
        verbose_name_plural = verbose_name
        ordering = ("-update_time",)

    # def save(self, force_insert=False, force_update=False, using=None,
    #          update_fields=None, update_total_fee=False):
    #     # 根据 update_total_fee 修改total_fee
    #     if update_total_fee:
    #         # 如果是促销价格 就按促销价格处理
    #         self.user_level = self.wm_order.supply_order.user.level
    #         # 标记订单为促销价格，促销价格不分佣金
    #         if self.goods.promotion:
    #             self.total_fee = self.goods.total_fee_promotion(self.num)
    #             self.is_promotion = True
    #             self.price = self.goods.promotion
    #         else:
    #             if self.wm_order.supply_order.user.level.level == 1:
    #                 self.total_fee = self.goods.total_fee(self.num)
    #                 self.price = self.goods.sales_price
    #             else:
    #                 self.total_fee = self.goods.total_fee_is_vip(self.num)
    #                 self.price = self.goods.sales_price_isvip
    #         self.cost = self.goods.cost
    #     super(WomaiChildOrder, self).save(force_insert=force_insert, force_update=force_update, using=using,
    #                                       update_fields=update_fields)
    #     return self

    def update_wm_order(self, wm_order):
        """
        更新外键
        :return:
        """
        self.wm_order = wm_order
        self.save()


# 收益管理
class OrderIncomeManager(models.Manager):
    # 创建推荐购物推荐人奖励（先不用了）
    def create_income(self, order):
        supply_order = order.wm_order.supply_order  # 基础订单
        goods = order.goods  # 商品
        buy_user = supply_order.user  # 购买用户
        referrer = buy_user.leader  # 推荐人
        if goods.is_vip_bag:
            # 非会员，购买会员礼包
            if buy_user.level.level == 1:
                order_type = 2
                income = referrer.level.cash_allot_level.first().income  # 推荐人所获得的收益
                # buy_user.recommend()  # 成为会员，会员升级
            # 复购会员礼包
            else:
                order_type = 3
                income = 0
        # 不是会员礼包
        else:
            order_type = 1
            # 如果此商品是促销商品
            if goods.promotion:
                income = 0
            else:
                allot = referrer.level.income_user_level_desc.get(buy_user_level=buy_user.level).allot  # 推荐人所获得的收益
                # 说明购买人是非会员，推荐人也是非会员
                if allot == 0:
                    income = 0
                # 说明购买人是非会员，推荐人是会员
                elif allot == 1:
                    income = (goods.sales_price - goods.sales_price_isvip) * order.num
                else:
                    income = (goods.sales_price - goods.sales_price_isvip) * allot * order.num
        if not self.filter(order=order, income=income, user=referrer).exists():
            order_income = self.create(
                order=order,
                base_order=supply_order,
                income=income,
                user=referrer,
                order_type=order_type,
                income_user_level=referrer.level,
            )
            return order_income
            # else:
            #     return self.filter(order=order, income=income, user=referrer)[0]

    # 创建推荐购物推荐人奖励
    def create_referee_income(self, order):
        supply_order = order.wm_order.supply_order  # 基础订单
        goods = order.goods  # 商品
        buy_user = supply_order.user  # 购买用户
        referrer = buy_user.leader  # 推荐人
        order_type = order.order_type
        if order_type == 1:
            if not order.is_promotion:
                allot = referrer.level.income_user_level_desc.get(buy_user_level=buy_user.level).allot  # 推荐人所获得的收益
                # 说明购买人是非会员，推荐人也是非会员
                if allot == 0:
                    income = 0
                # 说明购买人是非会员，推荐人是会员
                elif allot == 1:
                    income = (goods.sales_price - goods.sales_price_isvip) * order.num
                else:
                    income = (goods.sales_price - goods.sales_price_isvip) * allot * order.num
            else:
                income = 0
        elif order_type == 2:
            income = referrer.level.cash_allot_level.first().income  # 推荐人所获得的收益
        else:
            income = 0
        if income != 0 and not self.filter(order=order, income=income, user=referrer).exists():
            order_income = self.create(
                order=order,
                base_order=supply_order,
                income=income,
                user=referrer,
                order_type=order_type,
                income_user_level=referrer.level,
            )
            return order_income

    # 创建推荐人的推荐人奖励
    def create_other_income(self, base_income):
        for i in range(2, 11):
            if base_income.income <= 0:
                break
            else:
                income_user = base_income.user.leader
                # 如果有上级
                if income_user:
                    income_allot = base_income.user.level.lower_user_level_desc.get(
                        leader_user_level=income_user.level)
                    base_income = self.create(
                        order=base_income.order,
                        base_order=base_income.base_order,
                        income=base_income.income * income_allot.allot,
                        user=income_user,
                        order_type=base_income.order_type,
                        income_user_level=income_user.level,
                        lower_income=base_income,
                        income_type=i
                    )
                    # 如果之前的收益是会员礼包里的就算到第二层
                    if base_income.order_type == 2:
                        break
                else:
                    break

    def user_data_base(self, user):
        queryset = self.filter(user=user)
        return queryset.filter(Q(income_type__in=[1, 2], order_type__in=[1, 2]) & ~Q(income=0))

    def user_data(self, user):
        queryset = self.user_data_base(user)
        queryset = queryset.exclude(submit_state=3)
        return queryset

    def sales_data_base(self, user):
        return self.filter(user=user, income_type=1)

    def sales_data(self, user):
        queryset = self.sales_data_base(user)
        queryset = queryset.exclude(submit_state=3)
        return queryset

    # 今日数据
    def today_data(self, user):
        queryset = self.user_data(user)
        today = datetime.date.today()
        today_queryset = queryset.filter(create_date=today)
        # 收益
        today_income = today_queryset.aggregate(income=Sum("income")).get("income")
        today_income = today_income / 100 if today_income else 0
        today_income = "%.2f" % today_income

        # 销售额
        sales_data = self.sales_data(user)
        sales_data = sales_data.filter(create_date=today)
        today_sales_data = sales_data.filter(create_date=today)
        today_sales = today_sales_data.aggregate(sales=Sum("order__total_fee")).get("sales")
        today_sales = today_sales / 100 if today_sales else 0
        today_sales = "%.2f" % today_sales
        # 订单
        today_order = sales_data.count()
        return today_order, today_income, today_sales

    # 此月数据
    def this_mouth_data(self, user):
        queryset = self.user_data(user)
        this_mouth = GetDateTime.this_month()
        # 收益
        this_mouth_queryset = queryset.filter(create_date__gte=this_mouth)
        this_mouth_income = this_mouth_queryset.aggregate(income=Sum("income")).get("income")
        this_mouth_income = this_mouth_income / 100 if this_mouth_income else 0
        this_mouth_income = "%.2f" % this_mouth_income
        # 销售额
        sales_data = self.sales_data(user)
        sales_data = sales_data.filter(create_date__gte=this_mouth)
        this_mouth_sales_qs = sales_data.filter(create_date__gte=this_mouth)
        this_mouth_sales = this_mouth_sales_qs.aggregate(sales=Sum("order__total_fee")).get("sales")
        this_mouth_sales = this_mouth_sales / 100 if this_mouth_sales else 0
        this_mouth_sales = "%.2f" % this_mouth_sales
        # 订单
        this_mouth_order = this_mouth_sales_qs.count()
        return this_mouth_order, this_mouth_income, this_mouth_sales

    # 上月数据
    def last_mouth_data(self, user):
        queryset = self.user_data(user)
        last_mouth = GetDateTime.last_month()
        this_mouth = GetDateTime.this_month()
        # 收益
        last_mouth_queryset = queryset.filter(create_date__gte=last_mouth, create_date__lt=this_mouth)
        last_mouth_income = last_mouth_queryset.aggregate(income=Sum("income")).get("income")
        last_mouth_income = last_mouth_income / 100 if last_mouth_income else 0
        last_mouth_income = "%.2f" % last_mouth_income
        # 销售额
        sales_data = self.sales_data(user)
        last_mouth_sales = sales_data.filter(create_date__gte=last_mouth, create_date__lt=this_mouth)
        last_mouth_sales = last_mouth_sales.aggregate(sales=Sum("order__total_fee")).get("sales")
        last_mouth_sales = last_mouth_sales / 100 if last_mouth_sales else 0
        last_mouth_sales = "%.2f" % last_mouth_sales
        # 订单
        last_mouth_order = last_mouth_queryset.count()
        return last_mouth_order, last_mouth_income, last_mouth_sales

    # 总销售额
    @classmethod
    def total_sales_count(cls, sales_data):
        total_sales = sales_data.aggregate(sales=Sum("order__total_fee")).get("sales")
        return total_sales if total_sales else 0

    # 总数据
    def total_data(self, user):
        queryset = self.user_data(user)
        # 收益
        total_income = queryset.aggregate(income=Sum("income")).get("income")
        total_income = total_income / 100 if total_income else 0
        total_income = "%.2f" % total_income
        # 销售额
        sales_data = self.sales_data(user)
        total_sales = self.total_sales_count(sales_data)
        total_sales = total_sales / 100 if total_sales else 0
        total_sales = "%.2f" % total_sales
        # 订单
        total_order = sales_data.count()
        return total_order, total_income, total_sales

    # 以分为单位的可提现金额
    def transfer_income(self, user):
        queryset = self.user_data(user)
        queryset = queryset.filter(submit_state=2)
        income = queryset.aggregate(income=Sum("income")).get("income")
        income = income if income else 0
        return int(income), queryset

    # 可提现收益
    def income_sum(self, user):
        income, queryset = self.transfer_income(user)
        income /= 100
        income = "%.2f" % income
        return income, queryset

    # 记录申请退款，标记收益 已退款
    def update_refund_income(self, order):
        queryset = self.filter(order=order)
        queryset.update(
            submit_state=3
        )


# 收益
class OrderIncome(models.Model):
    submitState = ((1, "未结算"), (2, "待提现"), (3, "已退款"), (4, "已提现"))
    incomeType = ((1, "上下级"), (2, "跨级"))
    orderType = ((1, "正常商品"), (2, "会员礼包"), (3, "会员礼包复购"), (4, "加油权益"),)
    # updated_perf = models.BooleanField(default=False, verbose_name="已经更新过个人绩效了")
    user = models.ForeignKey(User, verbose_name="收益用户")
    income_user_level = models.ForeignKey("user_operation.LevelDesc", blank=True, null=True,
                                          verbose_name="当前推荐人用户身份",
                                          related_name="income_user_level_order_income")
    order = models.ForeignKey("WomaiChildOrder", verbose_name="子订单")
    base_order = models.ForeignKey("SupplyOrder", verbose_name="主订单")
    income = models.DecimalField(verbose_name="收入", default=0, max_digits=14, decimal_places=6,
                                 help_text="以分为单位")
    order_type = models.IntegerField(verbose_name="订单类型", default=1, db_index=True,
                                     help_text="当前购买是会员礼包还是会员礼包复购", choices=orderType)
    income_type = models.IntegerField(verbose_name="收入类型", choices=incomeType, db_index=True, default=1)
    create_time = models.DateTimeField(verbose_name="创建时间", default=timezone.now, db_index=True)
    create_date = models.DateField(verbose_name="创建日期", default=timezone.now, db_index=True)
    submit_state = models.IntegerField(verbose_name="提现状态", choices=submitState, default=1, db_index=True)
    transfer_record = models.ManyToManyField("TransferRecord", verbose_name="提现记录",
                                             related_name="income_transfer_record")
    lower_income = models.ForeignKey("self", related_name="income_lower_income", verbose_name="此收益由哪条收益带来",
                                     blank=True, null=True)
    objects = OrderIncomeManager()

    class Meta:
        verbose_name = "订单收益"
        verbose_name_plural = verbose_name
        ordering = ("-create_time",)


class TransferRecordManager(models.Manager):
    def transfer_views(self, amount, user, partner_trade_no, transfer_type=1, status=False):
        """
        创建提现记录
        :param wx_transfer_error_code: 微信付款
        :param amount: 钱数
        :param user: 用户
        :param partner_trade_no: 提现订单号
        :param status: 提现状态
        :return:
        """
        # 记录提现记录
        return self.create(
            transfer_type=transfer_type,
            cash=amount,
            user=user,
            partner_trade_no=partner_trade_no,
            status=status
            # wx_transfer_error_code=wx_transfer_error_code,
        )


# 提现记录
class TransferRecord(models.Model):
    transferType = ((1, "微信"), (2, "支付宝"), (3, "通联"))
    status = models.BooleanField(default=False, verbose_name="提现状态（成功/失败）")
    cash = models.IntegerField(verbose_name="提现金额")
    user = models.ForeignKey(User, verbose_name="提现用户")
    create_time = models.DateTimeField(auto_now_add=True)
    partner_trade_no = models.CharField(verbose_name="提现订单号", max_length=64, blank=True, null=True)
    transfer_type = models.IntegerField(choices=transferType, default=1, db_index=True)
    wx_transfer_error_code = models.OneToOneField("order.TransferErrorCode", blank=True, null=True,
                                                  verbose_name="微信提现错误码",
                                                  related_name="transfer_record_error_code")
    objects = TransferRecordManager()

    class Meta:
        verbose_name = "提现记录"
        verbose_name_plural = verbose_name


# 收藏
class Collect(models.Model):
    user = models.ForeignKey(User, related_name="collect_user", verbose_name="用户")
    goods = models.ForeignKey("Goods", related_name="collect_goods", verbose_name="商品")
    status = models.BooleanField(default=True, db_index=True, verbose_name="删除状态")
    create_time = models.DateTimeField(auto_now_add=True)
    update_time = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = "收藏"
        verbose_name_plural = verbose_name


class YFManager(models.Manager):
    # 通过首重 续重获取应收运费
    def get_price(self, province, type_142, type_143):
        post_fee = 0
        if type_142:
            yf_142 = self.get(province_name__contains=province, goods_type__goods_type=142)
            result = type_142 / 1000.0 - yf_142.sz
            if result <= 0:
                # 在首重范围内
                post_fee += yf_142.sz_price
            else:
                result = math.floor(result)
                post_fee += yf_142.sz_price + yf_142.xz_price * result

        if type_143:
            yf_143 = self.get(province_name__contains=province, goods_type__goods_type=143)
            result = type_143 / 1000.0 - yf_143.sz
            if result <= 0:
                # 在首重范围内
                post_fee += yf_143.sz_price
            else:
                result = math.floor(result)
                post_fee += yf_143.sz_price + yf_143.xz_price * result
        return post_fee

    # 获取补贴后的运费
    def get_post_fee(self, company_goods_num_list, province=None):
        """
        :param company_goods_num_list: [{"company_sign":"公司sign", "data": [{"goods":goods_obj, "num":3},{"goods":goods_obj, "num":2}]},]
        :param province: 当前用户所在省份
        :return: [{"company_sign":"公司sign", "receivable_post_fee":"应收运费", "post_fee":"实收运费",
                "data": [{"goods":goods_obj, "num":3},{"goods":goods_obj, "num":2}]},]
        """
        for data_list in company_goods_num_list:
            if data_list.get("company_sign") == "womaiwang" and province:
                type_142_weight, type_143_weight = Goods.objects.get_goods_weight(data_list.get("data"))
                receivable_post_fee = self.get_price(province, type_142_weight, type_143_weight)  # 应收运费
            else:
                if data_list and data_list.get("data"):
                    for one_data in data_list.get("data"):
                        if isinstance(one_data.get("goods"), Goods):
                            receivable_post_fee = one_data.get("goods").post_fee
                        else:
                            goods_obj = Goods.objects.get(id=one_data.get("goods"))
                            receivable_post_fee = goods_obj.post_fee
                            one_data["goods"] = goods_obj
                        if receivable_post_fee > 0:
                            break
                else:
                    receivable_post_fee = 0
            # 运费补贴, 并且是我买网商品
            if receivable_post_fee > 0 and data_list.get("company_sign") == "womaiwang":
                goods_num_list = data_list.get("data")
                gross_margin = Goods.objects.get_gross_margin(goods_num_list)
                post_fee = receivable_post_fee - gross_margin * 0.4  # 百分之40补贴运费
                post_fee = math.floor(post_fee)
                if post_fee < 0:
                    post_fee = 0
            else:
                post_fee = receivable_post_fee
            data_list["post_fee"] = post_fee
            data_list["receivable_post_fee"] = receivable_post_fee
        return company_goods_num_list

        # # 单产品获取运费
        # def get_post_fee_by_goods(self, goods, num, province=None):
        #
        #     """
        #     :param goods: 实例
        #     :param num:
        #     :param province: 实例
        #     :return:
        #     """
        #     sign = goods.company.sign
        #     data = [{"company_sign": sign, "data": [{"goods": goods, "num": num}]}]
        #     company_goods_num_list = self.get_post_fee(data, province=province)
        #     post_fee_data = company_goods_num_list[0]
        #     post_free = post_fee_data.get("post_fee")
        #     receivable_post_fee = post_fee_data.get("receivable_post_fee")
        #     return post_free, receivable_post_fee - post_free


# 运费
class YF(models.Model):
    sz_price = models.IntegerField(verbose_name="首重价格", help_text="以分为单位")
    xz_price = models.IntegerField(verbose_name="续重价格", help_text="以分为单位")
    goods_type = models.ForeignKey("GoodsType", verbose_name="类型", db_index=True)
    sz = models.IntegerField(verbose_name="首重", help_text="以KG为单位")
    province = models.ForeignKey("tools.Province", verbose_name="省份id", blank=True, null=True)
    province_name = models.CharField(verbose_name="省份描述", blank=True, null=True, max_length=32)
    objects = YFManager()

    class Meta:
        verbose_name = "运费"
        verbose_name_plural = verbose_name


# 物流公司
class PostCompany(models.Model):
    name = models.CharField(verbose_name="快递名字", max_length=64)
    code = models.CharField(verbose_name="编码", db_index=True, max_length=32)

    class Meta:
        verbose_name = "物流公司"
        verbose_name_plural = verbose_name


# 商品属性
class GoodsAttribute(models.Model):
    attr = models.CharField(verbose_name="属性", max_length=16, db_index=True)

    class Meta:
        verbose_name = "商品属性类别"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.attr


# 商品价格
class GoodsPrice(models.Model):
    stock = models.IntegerField(verbose_name="库存", default=999999)
    sales_price = models.IntegerField(verbose_name="销售价格", help_text="平台价，以分为单位", default=0)
    promotion = models.IntegerField(verbose_name="促销价格", default=0, help_text="比会员价格低")
    other_shop_sales_price = models.IntegerField(verbose_name="其他平台价格", help_text="其他平台价格", default=0)
    sales_price_isvip = models.IntegerField(verbose_name="会员销售价格", help_text="以分为单位", default=0)
    cost = models.IntegerField(verbose_name="成本价", help_text="以分为单位", default=0)
    goods = models.ForeignKey("Goods", verbose_name="商品", blank=True, null=True, related_name="goods_price_set")

    class Meta:
        verbose_name = "商品价格"
        verbose_name_plural = verbose_name

    def __str__(self):
        return "%s--%s: %s元" % (self.goods_id, self.goods.goodsname, self.sales_price / 100.0)

    # 获取会员价
    def get_vip_price(self):
        if self.goods.is_vip_bag:
            return self.sales_price * 0.75
        else:
            return self.sales_price_isvip

    # 获取购买时单价(返回价格，和订单状态 ((1, "正常商品"), (2, "会员礼包"), (3, "会员礼包复购")))
    def get_buy_price_attr(self, user):
        if self.goods.is_vip_bag:
            if user.is_authenticated:
                if user.level.level > 1:
                    return self.sales_price * 0.75, 3
                else:
                    return self.sales_price, 2
            else:
                return self.sales_price, 2
        elif self.promotion:
            if user.is_authenticated:
                if user.level.level > 1:
                    return self.promotion, 1
                else:
                    return self.sales_price, 1
            else:
                return self.sales_price, 1
        else:
            if user.is_authenticated:
                if user.level.level > 1:
                    return self.sales_price_isvip, 1
                else:
                    return self.sales_price, 1
            else:
                return self.sales_price, 1

    # 购买时的总价,单价,是否是促产品,
    def get_total_fee_price(self, user, num):
        is_promotion = False
        if self.goods.promotion:
            is_promotion = True
        price, order_type = self.get_buy_price_attr(user)
        total_fee = price * num
        return total_fee, price, is_promotion, order_type


# 商品属性值 多个属性值对应一个价格
class GoodsAttributeValue(models.Model):
    value = models.CharField(max_length=100, verbose_name="属性值")
    attribute = models.ForeignKey("GoodsAttribute", verbose_name="对应的属性", related_name="attr_value_set")
    price = models.ForeignKey("GoodsPrice", verbose_name="属性对应的价格", related_name="price_attr_value_set",
                              blank=True, null=True)

    class Meta:
        verbose_name = "商品属性值"
        verbose_name_plural = verbose_name

    def __str__(self):
        return "{}:{}".format(self.price.goods.goodsname, self.value)


# 推广图图片
class BasePopularImg(models.Model):
    img = models.ImageField(upload_to="shop/popular/")
    qr_code_size = models.CharField(max_length=16, verbose_name="二维码尺寸")
    qr_position = models.CharField(verbose_name="二维码位置", max_length=16)
    ordering = models.IntegerField(verbose_name="排序", default=1)

    class Meta:
        ordering = ("ordering",)
        verbose_name = "基础推广图"
        verbose_name_plural = verbose_name


# 二维码
class PopularQrCode(models.Model):
    user = models.ForeignKey(User, verbose_name="用户", related_name="popular_user_set")
    url = models.CharField(max_length=256, verbose_name="推广图地址")
    img = models.ForeignKey("BasePopularImg", verbose_name="推广图图片", related_name="popular_base_set",
                            on_delete=models.CASCADE)
    create_date = models.DateField(verbose_name="创建时间", default=timezone.now)

    class Meta:
        verbose_name = "用户推广图"
        verbose_name_plural = verbose_name


class RefundRecordManager(models.Manager):
    def create_refund(self, **kwargs):
        data = dict()
        data["refund_fee"] = kwargs.get("refund_fee")
        data["refund_type"] = kwargs.get("refund_type")
        data["out_refund_no"] = kwargs.get("out_refund_no")
        instance = self.create(
            **data
        )
        return instance


# 退款记录
class RefundRecord(models.Model):
    refund_fee = models.IntegerField(verbose_name="退款金额")
    create_time = models.DateTimeField(verbose_name="退款时间", default=timezone.now)
    refund_type = models.IntegerField(choices=SupplyOrder.pay_type, verbose_name="支付通道")
    out_refund_no = models.CharField(verbose_name="对应的退款订单号", db_index=True, max_length=64)
    objects = RefundRecordManager()

    class Meta:
        verbose_name = "退款记录"
        verbose_name_plural = verbose_name


# 太平洋白名单产品线
class TaiProjectLine(models.Model):
    name = models.CharField(verbose_name="产品线名称", max_length=64)

    class Meta:
        verbose_name = "太平洋白名单产品线"
        verbose_name_plural = verbose_name


# 太平洋医疗白名单
class BackDoorTai(models.Model):
    mobile = models.CharField(max_length=16, verbose_name="太平洋提供的白名单手机号", db_index=True)
    channel = models.ForeignKey("TaiProjectLine", verbose_name="太平洋白名单产品线")

    class Meta:
        verbose_name = "太平洋医疗白名单"
        verbose_name_plural = verbose_name


# # 商品属性
# class GoodsAttribute(models.Model):
#     attributeOption = ((1, "颜色"), (2, "尺寸"), (3, "自定义"))
#     attr = models.IntegerField(choices=attributeOption, verbose_name="属性")
#     # 一个商品有多个属性
#     goods = models.ForeignKey("Goods", verbose_name="商品", related_name="attribute_set")
#
#     class Meta:
#         verbose_name = "属性类别"
#         verbose_name_plural = verbose_name
#
#     def __str__(self):
#         return self.get_attr_display()
#
#
# # 商品价格
# class GoodsPrice(models.Model):
#     sales_price = models.IntegerField(verbose_name="销售价格", help_text="平台价，以分为单位", default=0)
#     promotion = models.IntegerField(verbose_name="促销价格", default=0, help_text="比会员价格低")
#     other_shop_sales_price = models.IntegerField(verbose_name="其他平台价格", help_text="其他平台价格", default=0)
#     sales_price_isvip = models.IntegerField(verbose_name="会员销售价格", help_text="以分为单位", default=0)
#     cost = models.IntegerField(verbose_name="成本价", help_text="以分为单位", default=0)
#
#     class Meta:
#         verbose_name = "商品价格"
#         verbose_name_plural = verbose_name
#
#
# # 商品属性值
# class GoodsAttributeValue(models.Model):
#     value = models.CharField(max_length=32, verbose_name="属性值")
#     attribute = models.ForeignKey("GoodsAttribute", verbose_name="对应的属性", related_name="attr_value_set")
#     price = models.ForeignKey("GoodsPrice", verbose_name="属性对应的价格", related_name="price_attr_value_set",
#                               blank=True, null=True)
#
#     class Meta:
#         verbose_name = "商品属性"
#         verbose_name_plural = verbose_name


class GGCardOrder(models.Model):
    key = models.CharField(max_length=32, verbose_name="key", db_index=True)
    cash = models.IntegerField(verbose_name="金额")
    re_bao = models.BooleanField(verbose_name="是否再来一包")
    ti_xian = models.BooleanField(verbose_name="是否已经提现")
    open_id = models.CharField(max_length=64, blank=True, null=True)  # 点击确定微信授权，并记录
    is_scan = models.BooleanField(verbose_name="是否已经扫过", default=False)  # 已经扫过了
    redeemed = models.BooleanField(verbose_name="已经兑换", default=False)

    class Meta:
        verbose_name = "active"
        verbose_name_plural = verbose_name
